package com.jiangjun.fetch.mongo;

import java.net.UnknownHostException;
import java.util.List;
import java.util.ResourceBundle;

import com.jiangjun.fetch.util.Page;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoOptions;
import com.mongodb.ServerAddress;

public abstract class AbstractMongoDBCache {

	public static Mongo mongo = null;
	public static DB db = null;

	static {
		MongoOptions mongoOptions = new MongoOptions();
		ResourceBundle bundle = ResourceBundle.getBundle("mongodb");
		String ip = bundle.getString("mongodb.ip");
		int port = Integer.parseInt(bundle.getString("mongodb.port"));
		String db_name = bundle.getString("mongodb.db");
		int maxActive = Integer.parseInt(bundle.getString("mongodb.maxActive"));
		int maxIdle = Integer.parseInt(bundle.getString("mongodb.maxIdle"));
		int maxWait = Integer.parseInt(bundle.getString("mongodb.maxWait"));
		try {
			ServerAddress address = new ServerAddress(ip, port);
			// 控制系统在发生连接错误时是否重试 ，默认为false --boolean
			mongoOptions.autoConnectRetry = true;
			// 每个主机允许的连接数（每个主机的连接池大小），当连接池被用光时，会被阻塞住 ，默认为10 --int
			mongoOptions.connectionsPerHost = maxActive;
			// 设置等待获取连接池连接的最大数，比如，connectionsPerHost
			// 是10，threadsAllowedToBlockForConnectionMultiplier
			// 是5，则最多有50个线程可以等待获取连接 --int
			mongoOptions.threadsAllowedToBlockForConnectionMultiplier = maxIdle;
			// 被阻塞线程从连接池获取连接的最长等待时间（ms） --int
			mongoOptions.threadsAllowedToBlockForConnectionMultiplier = maxWait;
			mongoOptions.socketKeepAlive = true;
			// #如果为true，驱动每次update后会发出一个getLastError命令来保证成功，默认为false --boolean
			mongoOptions.safe = false;
			mongo = new Mongo(address, mongoOptions);
			db = mongo.getDB(db_name);
		} catch (UnknownHostException e1) {
			e1.printStackTrace();
		}

	}

	public static void destory() {
		if (mongo != null)
			mongo = null;
		db = null;
		System.gc();
	}

	/**
	 * 添加Index
	 * 
	 * @param collection
	 * @param dbObject
	 */
	public abstract void addIndex(DBCollection collection, DBObject dbObject);

	/**
	 * 根据集合名称查询集合类
	 * 
	 * @param name
	 * @return
	 */
	public abstract DBCollection getCollectionByName(String name);

	/**
	 * 根据集合名称，查询集合的所有记录
	 * 
	 * @param name
	 * @return
	 */
	public abstract DBCursor queryCollection(String name);

	public abstract DBCursor queryCollectionByParam(String collectionName,
			BasicDBObject param, BasicDBObject sort);

	public abstract DBCursor queryCollectionByParam(String collectionName,
			Page page, BasicDBObject param, BasicDBObject sort);

	/**
	 * 保存数据
	 * 
	 * @param object
	 * @param collectionName
	 */
	public abstract void save(DBObject object, String collectionName);

	/**
	 * 批量保存数据
	 * 
	 * @param objs
	 * @param collectionName
	 */
	public abstract void saveList(List<DBObject> objs, String collectionName);

	/**
	 * 删除一条记录
	 * 
	 * @param collectionName
	 * @param object
	 */
	public abstract void removeDBObject(String collectionName, DBObject object);

	/**
	 * 删除一个集合
	 * 
	 * @param collectionName
	 */
	public abstract void dropOneCollection(String collectionName);

	/**
	 * 按条件查询一条数据
	 * 
	 * @param collectionName
	 * @param param
	 * @param sort
	 * @return
	 */
	public abstract DBObject queryOneByParam(String collectionName,
			BasicDBObject param, BasicDBObject sort);

	/**
	 * 根据条件查询所有记录
	 * 
	 * @param collectionName
	 * @param param
	 * @return
	 */
	public abstract DBCursor queryCollection(String collectionName,
			BasicDBObject param);

	/**
	 * 根据条件更新集合
	 * 
	 * @param collectionName
	 * @param param
	 * @param date
	 */
	public abstract void updateCollection(String collectionName,
			BasicDBObject param, BasicDBObject data);

	public abstract void findAndModifyCollection(String collectionName, DBObject query,
			DBObject object);
}
